<template>
  <div class="flex flex-col w-full h-full">
    <a-input-group class="mb-2 w-full" size="mini">
      <a-input
        :placeholder="props?.searchPlaceholder"
        allow-clear
        @input="changeKeyword"
        @clear="resetData"
      />
      <a-button
        @click="() => {
          isExpand ? treeRef.expandAll(false) : treeRef.expandAll(true)
          isExpand = ! isExpand
        }"
      >{{ isExpand ? '折叠' : '展开' }}</a-button>
      <slot name="treeAfterButtons"></slot>
    </a-input-group>
    <a-tree
      ref="treeRef"
      class="h-full w-full"
      :data="treeDatas"
      v-model:selected-keys="modelValue"
      :field-names="props.fieldNames"
      :block-node="true"
      @select="handlerSelect"
      v-bind="$attrs"
    >
      <template #icon v-if="props.icon"><component :is="props.icon" /></template>
      <template v-for="(_, name) in $slots" v-slot:[name]="data">
        <slot :name="name" v-bind="data"></slot>
      </template>
    </a-tree>
  </div>
</template>

<script setup>
  import { ref, watch, computed } from 'vue';

  const props = defineProps({
    modelValue: {type: Array},
    data: {type: Array},
    searchPlaceholder: {type: String},
    fieldNames: {
      type: Object, default: () => {
        return {title: 'label', key: 'value'}
      }
    },
    icon: {type: String, default: undefined},
  });

  const emit = defineEmits(['update:modelValue', 'click']);

  const treeRef = ref();
  const isExpand = ref(false);
  const baseTreeDatas = ref();
  const treeDatas = ref();

  const modelValue = computed({
    get() {
      return props.modelValue;
    },
    set(newVal) {
      emit('update:modelValue', newVal);
    }
  });

  watch(
    () => props.data,
    val => {
      treeDatas.value = val;
    },
    { immediate: true, deep: true },
  );

  const changeKeyword = (keyword) => {
    if (!keyword || keyword === '') {
      treeDatas.value = Object.assign(props.data, []);
      return false;
    }
    treeDatas.value = searchNode(keyword);
  }
  const resetData = () => {
    // treeDatas.value = baseTreeDatas.value;
    treeDatas.value = props.data;
  };
  const searchNode = (keyword) => {
    const loop = (data) => {
      let tree = [];
      data.map(item => {
        if (item.children && item.children.length > 0) {
          const temp = loop(item.children);
          tree.push(...temp);
        } else if (item[props.fieldNames['title']].indexOf(keyword) !== -1) {
          tree.push(item);
        }
        return tree;
      })
      return tree;
    }
    return loop(treeDatas.value);
  }
  const handlerSelect = async (item, data) => {
    modelValue.value = [item];
    emit('click', ...[item, data]);
  };

  defineExpose({
    treeRef,
  });
</script>

<style scoped lang="less">
  :deep(.arco-tree-node:hover) {
    background-color: var(--color-fill-2);
    border-radius: 3px;
  }
  :deep(.arco-tree-node-switcher) {
    margin-left: 2px;
  }
</style>
